package com.mallcloud.mall.app.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.mallcloud.mall.app.config.BaseConfig;
import com.mallcloud.mall.app.service.AppBrandService;
import com.mallcloud.mall.common.core.constant.CacheConstants;
import com.mallcloud.mall.product.api.entity.BrandModel;
import com.mallcloud.mall.product.api.entity.FloorModel;
import com.mallcloud.mall.product.service.BrandService;
import com.mallcloud.mall.product.service.FloorService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@AllArgsConstructor
public class AppBrandServiceImpl implements AppBrandService {
    private final FloorService floorService;
    private final BrandService brandService;
    private final BaseConfig baseConfig;

    @Override
    public List<Tree<Long>> treeByName(String name) {
        List<TreeNode<Long>> nodeList = this.treeNodeAll();
        if(CollectionUtil.isEmpty(nodeList)){
            log.error("楼层，品牌数据为空，无法生成楼层导览树");
            return Lists.newArrayList();
        }

        if(StrUtil.isNotBlank(name)){
            nodeList = nodeList.stream()
                    .filter(x -> {
                        if(x.getParentId()==0L){
                            return true;
                        }
                        if(String.valueOf(x.getName()).indexOf(name) != -1){
                            return true;
                        }
                        return false;
                    })
                    .collect(Collectors.toList());
        }
        return TreeUtil.build(nodeList, 0L);
    }

    @Override
    @Cacheable(value = CacheConstants.PROJECT_BRAND_TREE, unless = "#result==null or #result.size()==0")
    public List<TreeNode<Long>> treeNodeAll() {
        // 第一级楼层
        List<FloorModel> floorList = floorService.list(Wrappers.<FloorModel>lambdaQuery()
                .select(FloorModel::getFloorId, FloorModel::getName)
                .eq(FloorModel::getStatus, true)
                .orderByAsc(FloorModel::getSortOrder)
        );
        if (CollectionUtil.isEmpty(floorList)) {
            return Lists.newArrayList();
        }
        Map<Long, String> floorMap = floorList.stream().collect(Collectors.toMap(FloorModel::getFloorId, FloorModel::getName));

        // 第二级品牌
        List<BrandModel> brandList = brandService.list(Wrappers.<BrandModel>lambdaQuery()
                .select(BrandModel::getBrandId,
                        BrandModel::getAddrNumber,
                        BrandModel::getFloorId,
                        BrandModel::getImgUrl,
                        BrandModel::getName
                )
                .eq(BrandModel::getStatus, true)
                .orderByAsc(BrandModel::getSortOrder)
        );
        if (CollectionUtil.isEmpty(brandList)) {
            return Lists.newArrayList();
        }

        // 合并数组
        Long maxId = 0L;
        List<TreeNode<Long>> collect = new ArrayList<>();
        for (FloorModel floor : floorList) {
            collect.add(new TreeNode(
                    floor.getFloorId(),
                    0L,
                    floor.getName(),
                    floor.getSortOrder()
            ));
            if (floor.getFloorId() > maxId) maxId = floor.getFloorId();
        }
        maxId++;

        for (BrandModel brand : brandList) {
            TreeNode<Long> node = new TreeNode(
                    maxId,
                    brand.getFloorId(),
                    brand.getName(),
                    brand.getSortOrder()
            );
            maxId++;
            // 扩展属性
            Map<String, Object> extra = new HashMap<>();
            if (StrUtil.isNotBlank(brand.getImgUrl())) {
                extra.put("icon", String.format("%s%s", baseConfig.getNginxUrl(), StrUtil.subAfter(brand.getImgUrl(), StrUtil.SLASH, true)));
            }
            if(floorMap.containsKey(brand.getFloorId())){
                extra.put("floorName", floorMap.get(brand.getFloorId()));
            }
            extra.put("tempId", brand.getBrandId());
            extra.put("addrNumber", brand.getAddrNumber());
            node.setExtra(extra);
            collect.add(node);
        }

        return collect;
    }
}
